﻿// HSS.Logging.Management.LogAttachmentViewer.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.html
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       LogAttachmentViewer.cs
// Author:     HSS\gbanta
// Created:    08/12/2010
// Modified:   12/04/2010
// ----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Globalization;

namespace HSS.Logging.Management
{
	internal partial class LogAttachmentViewer : HSS.Forms.Docking.DockContent
	{
		delegate void displayAttachmentDelegate(LogEntryAttachment val);
		delegate void displayExceptionDelegate(Exception val);
		private readonly object displayAttachmentLock = new object();
		private int currentView = 0;
		private LogEntryAttachment attachment;
        
		public LogAttachmentViewer()
		{
			InitializeComponent();
		}

		/// <summary>
		/// Display an Attachment
		/// </summary>
		/// <param name="att">The LogEntryAttachment to display</param>
		public void DisplayAttachment(LogEntryAttachment att)
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new displayAttachmentDelegate(DisplayAttachment), att);
				return;
			}

			try
			{
				if (att.AttachmentID == 0)
				{
					this.ClearAttachment();
					return;
				}

				if (string.IsNullOrEmpty(att.LocalFileName))
				{
					this.ClearAttachment();
					this.lbgAttachmentHeader.Text = "Attachment not found ...";
					return;
				}

				attachment = att;

				#region Display

				lock (displayAttachmentLock)
				{
					#region Display

					#region Get File Size
					FileInfo fi = new FileInfo(att.LocalFileName);
					string sizeIn = "bytes";
					double size = fi.Length;
					if (fi.Length > ((1024 * 1024) * 1024))
					{
						sizeIn = "GB";
						size = size / ((1024 * 1024) * 1024);
					}
					else if (fi.Length > (1024 * 1024))
					{
						sizeIn = "MB";
						size = size / (1024 * 1024);
					}
					else if (fi.Length > 1024)
					{
						sizeIn = "KB";
						size = size / 1024;
					}
					#endregion

					// Gets a NumberFormatInfo associated with the en-US culture.
					NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat;
					this.lbgAttachmentHeader.Text = att.DisplayName + "   [ " + size.ToString("N", nfi) + " " + sizeIn + " ]";

					#region Display appropriate viewer
					switch (att.Extension.ToLower())
					{
						case ".xml":
						case ".html":
						case ".htm":
						case ".xsd":
						case ".xsl":
						case ".xhtml":
						case ".resx":
							#region Web Based Content
							this.wbbAttachment.Navigate(att.LocalFileName);
							if (this.wbbAttachment.Dock != DockStyle.Fill)
								this.wbbAttachment.Dock = DockStyle.Fill;
							if (currentView != 2)
							{
								currentView = 2;
								this.wbbAttachment.BringToFront();
							}
							#endregion
							break;

						case ".gif":
						case ".png":
						case ".tiff":
						case ".tif":
						case ".bmp":
						case ".ico":
						case ".jpg":
							#region Image based Content
							this.pbxAttachment.ImageLocation = att.LocalFileName;
							this.pbxAttachment.LoadAsync();
							if (this.pbxAttachment.Dock != DockStyle.Fill)
								this.pbxAttachment.Dock = DockStyle.Fill;
							if (currentView != 1)
							{
								currentView = 1;
								this.pbxAttachment.BringToFront();
							}
							#endregion
							break;

						case ".rtf":
							#region Text based content
							this.rtfAttachment.LoadFile(att.LocalFileName);
							if (this.rtfAttachment.Dock != DockStyle.Fill)
								this.rtfAttachment.Dock = DockStyle.Fill;
							if (currentView != 0)
							{
								currentView = 0;
								this.rtfAttachment.BringToFront();
							}
							#endregion
							break;

						case ".txt":
						case ".csv":
						case ".tsv":
						case ".vsi":
						case ".bin":
							#region Text based content
							this.rtfAttachment.LoadFile(att.LocalFileName, RichTextBoxStreamType.PlainText);
							if (this.rtfAttachment.Dock != DockStyle.Fill)
								this.rtfAttachment.Dock = DockStyle.Fill;
							if (currentView != 0)
							{
								currentView = 0;
								this.rtfAttachment.BringToFront();
							}
							#endregion
							break;

						default:
							#region Unknown content
							string content = "<span><strong>Attachment: </strong>" + att.DisplayName + "<br /><br />This Attachment must be viewed in its native Viewer/Editor.</span><br /><br /><a href=\"" + att.LocalFileName + "\" type=\"" + att.ContentType + "\" target=\"_blank\" >Click here to view Attachment</a>";
							if (null != this.wbbAttachment.Document)
								this.wbbAttachment.Document.Body.InnerHtml = content;
							if (this.wbbAttachment.Dock != DockStyle.Fill)
								this.wbbAttachment.Dock = DockStyle.Fill;
							if (currentView != 2)
							{
								currentView = 2;
								this.wbbAttachment.BringToFront();
							}
							#endregion
							break;
					}
					#endregion

					this.mnuSaveAsToolStripMenuItem.Enabled = true;
					this.Cursor = Cursors.Default;

					#endregion
				}
				#endregion
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.ToString());
				this.ClearAttachment();
			}
		}
		/// <summary>
		/// Display the exception enocuntered attempting to retrieve an Attachment
		/// </summary>
		/// <param name="Error">The <see cref="System.Exception"/> encountered</param>
		public void DisplayException(Exception Error)
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new displayExceptionDelegate(DisplayException), Error);
				return;
			}

			try
			{
				#region Display
				lock (displayAttachmentLock)
				{
					this.lbgAttachmentHeader.Text = "Exceptions encountered...";

					StringBuilder content = new StringBuilder(System.Web.HttpUtility.HtmlEncode(Error.ToString()));
					content.Replace("\r\n", "<br />");
					string errString = content.ToString();
					content.Remove(0, content.Length);
					content.Append("<div><span><strong>Exceptions encountered retrieving attachment:</strong><br /><br />");
					content.Append(System.Web.HttpUtility.HtmlEncode(Error.Message));
					content.Append("</span><br /><br /><span><strong>Exception source:</strong><br /><br />");
					content.Append(System.Web.HttpUtility.HtmlEncode(Error.Source));
					content.Append("</span><br /><br /><span><strong>Exception detail:</strong><br /><br />");
					content.Append(errString);
					content.Append("</span></div>");
					if (null != this.wbbAttachment.Document)
						this.wbbAttachment.Document.Body.InnerHtml = content.ToString();
					if (this.wbbAttachment.Dock != DockStyle.Fill)
						this.wbbAttachment.Dock = DockStyle.Fill;
					if (currentView != 2)
					{
						currentView = 2;
						this.wbbAttachment.BringToFront();
					}

					this.mnuSaveAsToolStripMenuItem.Enabled = false;
					this.Cursor = Cursors.Default;

				}
				#endregion
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.ToString());
				this.ClearAttachment();
			}
		}
		/// <summary>
		/// Display a message indicating that an attempt to download is in progress
		/// </summary>
		public void DisplayDownloading()
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new MethodInvoker(DisplayDownloading));
				return;
			}

			try
			{
				#region Display
				lock (displayAttachmentLock)
				{
					this.lbgAttachmentHeader.Text = "Downloading Attachment ...";

					if (null != this.wbbAttachment.Document)
						this.wbbAttachment.Document.Body.InnerHtml = "";
					if (this.wbbAttachment.Dock != DockStyle.Fill)
						this.wbbAttachment.Dock = DockStyle.Fill;
					if (currentView != 2)
					{
						currentView = 2;
						this.wbbAttachment.BringToFront();
					}
					this.mnuSaveAsToolStripMenuItem.Enabled = false;
				}
				#endregion
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.ToString());
				this.ClearAttachment();
			}
		}
		/// <summary>
		/// Clear the current attachment
		/// </summary>
		public void ClearAttachment()
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new MethodInvoker(ClearAttachment));
				return;
			}

			try
			{
				this.mnuSaveAsToolStripMenuItem.Enabled = false;

				this.lbgAttachmentHeader.Text = "No Attachment";

				this.Cursor = Cursors.Default;

				this.wbbAttachment.Dock = DockStyle.None;
				this.pbxAttachment.Dock = DockStyle.None;
				this.rtfAttachment.Dock = DockStyle.None;
				this.currentView = -1;

				this.wbbAttachment.Left = -20000;
				this.pbxAttachment.Left = -20000;
				this.rtfAttachment.Left = -20000;
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.ToString());
			}
		}

		private void mnuSaveAsToolStripMenuIte_Click(object sender, EventArgs e)
		{
			//
			// Save the currently selected File Attachment
			//
			using (SaveFileDialog sfd = new SaveFileDialog())
			{
				sfd.FileName = attachment.DisplayName;
				if (sfd.ShowDialog() == DialogResult.OK)
					File.Copy(attachment.LocalFileName, sfd.FileName);
			}
		}
		private void rtfAttachment_LinkClicked(object sender, LinkClickedEventArgs e)
		{
			System.Diagnostics.Process.Start(e.LinkText);
		}

	}
}